package com.apache.passport.service.plugins;

import com.apache.api.manager.PluginConnector;
import com.apache.api.vo.ParamsVo;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SystemTools;
import com.apache.database.db.IDao;
import com.apache.database.model.MethodParam;
import com.apache.passport.common.DesUtils;
import com.apache.passport.common.LoginCacheErrTimer;
import com.apache.passport.common.PassPortConst;
import com.apache.passport.entity.*;
import com.apache.passport.manager.LoginInfoManager;
import com.apache.tools.DateUtils;

import java.util.Date;

/**
 * description:  用户登录插件
 *
 * @author Hou Dayu 创建时间：2016-12-19
 */
public class LoginUserPlugin extends SuperPluginConnector {

//    protected IDao uctUserDao;

    protected IDao blackRosterDao;

    private LoginInfoManager loginInfoManager;

//    public void setUctUserDao(IDao uctUserDao) {
//        this.uctUserDao = uctUserDao;
//    }

    /**
     * TODO 用户密码校验
     *
     * @see PluginConnector#execute(ParamsVo)
     */
    @Override
    public Object execute(ParamsVo vo) throws Exception {
        boolean flag = false;
        String tokenId = (String) vo.getParams("tokenId");
        String sessionId = (String) vo.getParams("sessionId");
        String remoteIp = (String) vo.getParams("remoteIp");
        String synFlag = SystemTools.getInstance().getValue("synFlag");
        ParamsVo<UctUser> vos = new ParamsVo<UctUser>();
        vos = vo;
        //登录前首先从数据库中查询下该用户是否存在于黑名单中
        BlackRoster br = (BlackRoster) getBrInfoByIp(vo);
        if (!Validator.isEmpty(br)) {
            LonErrToken token = new LonErrToken();
            token.setLoginCount("12");
            token.setLoginTime(br.getBrCreatetime());
            //2015年1月29日13:02:54  将用户名添加到错误token中
            token.setUserEname(vos.getObj().getUserEname());
            token.setCacheId(remoteIp + br.getBrAccount());
            //存储缓存
            PassPortConst.setLonErrToken(remoteIp, br.getBrAccount(), token);

            return false;
        }

        //查询用户是否存在
        UctUser obj = (UctUser) getInfoByEname(vo);

        //判断用户是否存在
        if (!Validator.isEmpty(obj)) {
            String upass = (String) vo.getParams("userPass");
            //判断密码是否正确
            if ((obj.getUserPass()).equalsIgnoreCase(upass)) {
                //虽然密码正确,但是需要判断下之前缓存中是否存在该用户的登陆错误信息,如果存在,则依然返回等待
                LonErrToken tokenE = PassPortConst.getLonErrToken(remoteIp, obj.getUserEname());
                if (!Validator.isEmpty(tokenE)) {
                    if(LoginCacheErrTimer.getInstance().checkErrToken(remoteIp,obj.getUserEname())){
                        String count = tokenE.getLoginCount();
                        int c = Integer.parseInt(count);
                        if ("3".equals(tokenE.getLoginCount()) || "6".equals(tokenE.getLoginCount())
                                || "9".equals(tokenE.getLoginCount()) || c > 12) {
                            //如果错误次数等于以上几个参数,也同样需要校验下时间是否已经过期,防止时间已过,且登录密码正确,却一直没有更新缓存
                            //setErrToken(vo, remoteIp, br, obj);
                            LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
                            return false;
                        }
                    }
                }

                //将所有项存储到对象中
                Token token = new Token();
                token.setLoginTime(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm"));
                vo.setParams("tokenId", tokenId);
                token.setTokenId(tokenId);
                token.setSessionId(sessionId);
                flag = true;
                //校验密码成功后,则表示用户存在且已经登录成功,则将用户数据写入到缓存中
                String desEname = DesUtils.getInstance().encrypt(obj.getUserEname());
                token.setUserEname(desEname);
                if (!Validator.isNull(obj.getMobile())) {
                    String desMobile = DesUtils.getInstance().encrypt(obj.getMobile());
                    token.setMobile(desMobile);
                }
                if (!Validator.isNull(obj.getEmail())) {
                    String desEmail = DesUtils.getInstance().encrypt(obj.getEmail());
                    token.setEmail(desEmail);
                }
                token.setCustomerType(obj.getCustomerType());
                token.setUserLevel(obj.getUserLevel());
                token.setUserType(obj.getUserType());
                //token.setRegSource(obj.getRegSource());
                //添加cname
                if (!Validator.isNull(obj.getUserCname())) {
                    String desCname = obj.getUserCname();
                    token.setUserCname(desCname);
                }
                //获取数据库中上次登录的信息
                ParamsVo<LoginInfo> param = new ParamsVo<LoginInfo>();
                param.setInfoId(obj.getUserEname());
                LoginInfo loginInfo = (LoginInfo) loginInfoManager.getInfoById(param);
                token.setLoginInfo(loginInfo);
                //如果登录成功后,清空错误记录缓存
                PassPortConst.detLonErrToken(remoteIp, obj.getUserEname());

                //如果属于单态,使用单态只应用在登录场景,如果在飞单态情况下登录成功,
                //其修改了配置文件,使用单态,则无法启到单态登录的效果,因为此功能只添加至登录操作中
                PassPortConst.setToken("1".equals(synFlag) ? true : false, tokenId, token);

            } else {
                //setErrToken(vo, remoteIp, br, obj);
                LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
            }
        } else {
            //setErrToken(vo, remoteIp, br, obj);
            LoginCacheErrTimer.getInstance().setErrToken(vos, remoteIp, br, obj);
        }
        return flag;
    }

    /**
     * description:  根据ename,手机号,邮箱查询用户信息
     */
    /*public Object getInfoByEname(ParamsVo<UctUser> vo) {
        String userEname = vo.getObj().getUserEname();
        if (Validator.isNull(userEname)) {
            return null;
        }
        String sql = uctUserDao.getSql(3);// from UctUser where userEname :=userEname

        String mobileLogin = SystemTools.getInstance().getValue("mobileLogin");
        String emailLogin = SystemTools.getInstance().getValue("emailLogin");

        if ("1".equals(mobileLogin)) {
            sql += "or mobile :=userEname ";
        }
        if ("1".equals(emailLogin)) {
            sql += "or email :=userEname ";
        }

        MethodParam param = new MethodParam("ByUserEname", "", sql,
                "com.apache.passport.entity.UctUser");
        param.setParams("userEname", userEname);
        if ("1".equals(mobileLogin)) {
            param.setParams("mobile", userEname);
        }
        if ("1".equals(emailLogin)) {
            param.setParams("email", userEname);
        }
        return uctUserDao.selectSingle(param);
    }*/

    /**
     * description:  根据IP及用户名获取黑名单
     *
     * @param vo
     * @return
     */
    public Object getBrInfoByIp(ParamsVo<UctUser> vo) {
        String remoteIp = (String) vo.getParams("remoteIp");
        String userEname = (String) vo.getParams().get("userEname");
        //只验证用户名
        String sql = blackRosterDao.getSql(4);
        if (!Validator.isNull(remoteIp)) {
            sql += " and brIpaddress :=brIpaddress ";
        }
        MethodParam param = new MethodParam("ByIpOrUserEname", "", sql,
                BlackRoster.class.getName());
        param.setParams("brIpaddress", remoteIp);
        param.setParams("brAccount", userEname);
        return blackRosterDao.selectSingle(param);
    }

    public void setLoginInfoManager(LoginInfoManager loginInfoManager) {
        this.loginInfoManager = loginInfoManager;
    }

    public void setBlackRosterDao(IDao blackRosterDao) {
        this.blackRosterDao = blackRosterDao;
    }

}
